package com.biu.billiards.webSocket;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.biu.billiards.service.impl.OrderServiceImpl;
import com.biu.billiards.service.impl.UserServiceImpl;
import com.biu.billiards.task.AsyncTask;
import org.apache.commons.lang.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Websocket处理器
 */

@Component
public class NetgateHandler extends TextWebSocketHandler {

    @Autowired
    private OrderServiceImpl orderService;


    /*
     * 网关连接集合
     * 第一级：设备序列号 sn
     * 第二级：用户唯一标识 openid
     */
    private static ConcurrentHashMap<String, ConcurrentHashMap<String, WebSocketSession>> netgates = new ConcurrentHashMap<String,ConcurrentHashMap<String,WebSocketSession>>();



    /**
     * 处理前端发送的文本信息
     * js调用websocket.send时候，会调用该方法
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        if(!session.isOpen()) {
            System.out.println("连接已关闭 ，不再处理该连接的消息！");
            return;
        }

        System.out.println("sessionaaaaaa");
        System.out.println(session);
        System.out.println(message);
        String mes = ObjectUtils.toString(message.getPayload(),"");
        String pid = session.getAttributes().get("WEBSOCKET_PID").toString();
        String sn = session.getAttributes().get("WEBSOCKET_SN").toString();
        if(message==null || "".equals(mes)){
            System.out.println(getSysDate()+"============接收到空消息，不予处理。");
        }else if(mes.length()==1){
            //心跳消息过滤掉
            return;
        }else {

            System.out.println("mes");
            System.out.println(mes);
          //  System.out.println(orderService.orderNumber());


            if (orderService.orderNumber()){
                sendMsgToNetgateSn("33","update");
            }else {
                sendMsgToNetgateSn("33","无变化");
            }


        }
    }


    /**
     * 当新连接建立的时候，被调用
     * 连接成功时候，会触发页面上onOpen方法
     *
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println(getSysDate()+"============正在初始化连接："+session.getId());
        try {
            //初始化连接，把session存储起来
            this.initUsers(session);
        } catch (Exception e) {
            System.out.println(getSysDate()+"============初始化连接异常-开始："+e.getMessage());
            e.printStackTrace();
            System.out.println(getSysDate()+"============初始化连接异常-结束："+e.getMessage());
        }
        System.out.println(getSysDate()+"============初始化连接完成："+session.getId());
    }

    /**
     * 当连接关闭时被调用
     *
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println(getSysDate()+"============正在关闭连接："+session.getId()+",isOpen:"+session.isOpen()+";code："+status.getCode());
        try {
            System.out.println("断开连接状态值"+status.getCode());
            this.removeSession(session);
        } catch (Exception e) {
            System.out.println(getSysDate()+"============关闭连接异常-开始："+e.getMessage());
            e.printStackTrace();
            System.out.println(getSysDate()+"============关闭连接异常-结束："+e.getMessage());
        }
        System.out.println(getSysDate()+"============正在关闭完成："+session.getId()+",isOpen:"+session.isOpen()+";code："+status.getCode());
    }

    /**
     * 传输错误时调用
     *
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println(getSysDate()+"============发生传输错误："+session.getId()+";session.isOpen():"+session.isOpen()+";exception："+exception.getMessage());
        exception.printStackTrace();
        if (session.isOpen()) {
            //try { session.close(); } catch (Exception e) {e.printStackTrace();}
        }else {
            try {
                this.removeSession(session);
            } catch (Exception e) {
                System.out.println(getSysDate()+"============传输错误处理异常-开始："+e.getMessage());
                e.printStackTrace();
                System.out.println(getSysDate()+"============传输错误处理异常-结束："+e.getMessage());
            }
        }
        System.out.println(getSysDate()+"============错误处理结束："+session.getId()+";session.isOpen():"+session.isOpen()+";exception："+exception.getMessage());
    }


    public synchronized void sendMsgToNetgateSn(String sn, String msg)  {
        if(netgates.size()>0 && netgates.containsKey(sn) && !netgates.get(sn).isEmpty()){
            //获取EID对应的后台管理连接 多个
            for (WebSocketSession ws: netgates.get(sn).values()){
                System.out.println("对网关指令开始发送啦:sn="+sn+"消息内容"+msg);
                try {ws.sendMessage(new TextMessage(msg));} catch (IOException e) {System.out.println(getSysDate()+"发生了异常："+e.getMessage());e.printStackTrace();continue;}
            }
        }
    }

    //连接接入的处理方法
    private synchronized void initUsers(WebSocketSession session){
        String pid = (String) session.getAttributes().get("WEBSOCKET_PID");
        String sn = (String) session.getAttributes().get("WEBSOCKET_SN");
        String openid = (String) session.getAttributes().get("WEBSOCKET_OPENID");
        if(StringUtils.isNotEmpty(pid) && StringUtils.isNotEmpty(sn) && StringUtils.isNotEmpty(openid)){
            ConcurrentHashMap<String,WebSocketSession> netgate = netgates.get(sn);
            if(netgate == null){
                netgate = new ConcurrentHashMap<String,WebSocketSession>();
            }
            WebSocketSession session_exist = netgate.get(sn);
            if(session_exist!=null) {
                System.out.println("检测到相同SN重复连接,SN:"+sn+",连接ID:"+session_exist.getId()+",准备清理失效的连接。。。");
                try {session_exist.close();} catch (IOException e) {e.printStackTrace();}
            }
            netgate.putIfAbsent(openid, session);
            netgates.put(sn,netgate);
        }
    }

    //连接被关闭时处理集合
    private synchronized void removeSession(WebSocketSession session){
        System.out.println("sessionsss");
        System.out.println(session);
        String sn = (String) session.getAttributes().get("WEBSOCKET_SN");
        String openid = (String) session.getAttributes().get("WEBSOCKET_OPENID");
        if(netgates.get(sn).containsKey(openid)) {
            WebSocketSession exist_session = netgates.get(sn).get(openid);
            //确保是同一个session 不是同一个session则不应该进行下一步的处理
            if(exist_session.getId()!=null && exist_session.getId().equals(session.getId())) {
                netgates.get(sn).remove(openid);
                System.out.println("有一网关连接关闭！SN："+sn+",当前在线数量为"+netgates.get(sn).keySet().size());
            }else {
                System.out.println("检测到关闭session异常,程序中断处理,关闭sessionId："+session.getId()+",当前实际sessionId:"+exist_session.getId());
            }
        }else {
            System.out.println("检测到关闭session异常,程序中断处理,系统中未找到对应的session,Sn="+sn+"openid="+openid);
        }
    }

    private String getSysDate() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        return df.format(new Date());
    }
}
